﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using PlanningGIS.Win.Controls;
using PlanningGIS.ArcGIS;

namespace PlanningGIS.Framework.Controls
{
    /// <summary>
    /// 功能：显示所选要素的节点坐标列表
    /// </summary>
    public partial class FrmPtsCoord : Office2007Form
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public FrmPtsCoord()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 是否存在Z值
        /// </summary>
        bool bHasZ = false;
        
        /// <summary>
        /// 地图关联对象
        /// </summary>
        private IHookHelper _HookHelper = null;

        /// <summary>
        /// 设置地图关联对象
        /// </summary>
        public object Hook
        {
            set
            {
                _HookHelper = new HookHelper();
                _HookHelper.Hook = value;
            }
        }
        
        /// <summary>
        /// 要显示的坐标的空间对象
        /// </summary>
        public IGeometry Geometry { private get; set; }

        /// <summary>
        /// 加载窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmPtsCoord_Load(object sender, EventArgs e)
        {
            combo_Scale.SelectedIndex = 2;
        }

        /// <summary>
        /// 显示节点坐标
        /// </summary>
        public void ShowCoordinates()
        {
            ShowCoordinate();
            DrawVertexs(0, false);
        }

        /// <summary>
        /// 显示空间对象
        /// </summary>
        private void ShowCoordinate()
        {
            if (Geometry == null) return;
            lvwGeoPart.Items.Clear();
            try
            {
                ISpatialReference sr = Geometry.SpatialReference;
                bHasZ = sr.HasZPrecision();
                if (!bHasZ) coordGrid.Columns.RemoveAt(3);
                switch (Geometry.GeometryType)
                {
                    case esriGeometryType.esriGeometryPoint:
                        lvwGeoPart.Items.Add("1");
                        lvwGeoPart.Items[0].Selected = true;
                        return;
                    case esriGeometryType.esriGeometryMultipoint:
                    case esriGeometryType.esriGeometryPolyline:
                    case esriGeometryType.esriGeometryPolygon:
                        IGeometryCollection geoCollection = Geometry as IGeometryCollection;
                        for (int i = 0; i < geoCollection.GeometryCount; i++)
                        {
                            lvwGeoPart.Items.Add((i + 1).ToString());
                        }
                        if (lvwGeoPart.Items.Count > 0) lvwGeoPart.Items[0].Selected = true;
                        break;
                }
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(ex.Message);
            }
        }
        
        /// <summary>
        /// 显示坐标值
        /// </summary>
        /// <param name="partIndex"></param>
        private void ShowCoordinate(int partIndex)
        {
            if (Geometry == null) return;
            try
            {
                int precision = 6;
                IGeometryCollection geoCollection = Geometry as IGeometryCollection;
                IGeometry geo = geoCollection.get_Geometry(partIndex);
                IPointCollection ptCol = geo as IPointCollection;
                for (int i = 0; i < ptCol.PointCount; i++)
                {
                    IPoint pt = ptCol.get_Point(i);
                    ListViewItem lstItem = coordGrid.Items.Add(Convert.ToString(i + 1));
                    lstItem.Tag = pt;
                    if (precision >= 0)
                    {
                        lstItem.SubItems.Add(pt.X.ToString("F" + precision));
                        lstItem.SubItems.Add(pt.Y.ToString("F" + precision));
                    }
                    else
                    {
                        lstItem.SubItems.Add(pt.X.ToString());
                        lstItem.SubItems.Add(pt.Y.ToString());
                    }

                    if (bHasZ)
                    {
                        if (precision >= 0)
                        {
                            lstItem.SubItems.Add(pt.Z.ToString("F" + precision));
                        }
                        else
                        {
                            lstItem.SubItems.Add(pt.Z.ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(ex.Message);
            }
        }
        
        /// <summary>
        /// 绘制节点
        /// </summary>
        /// <param name="hdc"></param>
        /// <param name="bChangeHdc"></param>
        public void DrawVertexs(int hdc, bool bChangeHdc)
        {
            if (Geometry == null || _HookHelper == null) return;
            IPointCollection ptColln = Geometry as IPointCollection;
            if ((ptColln == null) || (ptColln.PointCount <= 0)) { return; }
            IGraphicsContainer pg = _HookHelper.ActiveView.GraphicsContainer;
            ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol();
            simpleMarkerSymbol.Size = 3;
            simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSDiamond;
            IElement element;
            IMarkerElement markerElement;
            for (int i = 0; i < ptColln.PointCount; i++)
            {
                markerElement = new MarkerElement() as IMarkerElement;
                markerElement.Symbol = simpleMarkerSymbol;
                element = (IElement)markerElement;
                element.Geometry = ptColln.get_Point(i);
                pg.AddElement(element, 2);
            }

            //the last Point
            if ((Geometry.GeometryType == esriGeometryType.esriGeometryPolygon) || (Geometry.GeometryType == esriGeometryType.esriGeometryPolyline))
            {
                IRgbColor rgbColor = new RgbColor();
                rgbColor.Red = 255;
                simpleMarkerSymbol.Color = (IColor)rgbColor;
                markerElement = new MarkerElement() as IMarkerElement;
                markerElement.Symbol = simpleMarkerSymbol;
                element = (IElement)markerElement;
                element.Geometry = ptColln.get_Point(0);
                pg.AddElement(element, 2);
            }

            IRgbColor rgbColor2 = new RgbColor();
            rgbColor2.Blue = 254;
            rgbColor2.Green = 254;
            simpleMarkerSymbol.Color = rgbColor2;

            markerElement = new MarkerElement() as IMarkerElement;
            markerElement.Symbol = simpleMarkerSymbol;
            IElement element2 = (IElement)markerElement;
            element2.Geometry = ptColln.get_Point(0);
            pg.AddElement((IElement)element2, 0);
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, _HookHelper.ActiveView.Extent);
        }

        /// <summary>
        /// 选择坐标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void coordGrid_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (coordGrid.SelectedItems.Count == 0 || _HookHelper == null) return;
            try
            {
                IEnvelope env = new Envelope() as IEnvelope;
                IPoint pt = coordGrid.SelectedItems[0].Tag as IPoint;
                env = Geometry.Envelope;
                env.Expand(3, 3, false);
                _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, env);
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(ex.Message);
            }
        }

        /// <summary>
        /// 选择空间对象
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lvwGeoPart_SelectedIndexChanged(object sender, EventArgs e)
        {
            coordGrid.Items.Clear();
            if (lvwGeoPart.SelectedItems.Count == 0) return;
            int index = Convert.ToInt32(lvwGeoPart.SelectedItems[0].Text) - 1;
            int precision = 6;
            try
            {
                
                switch (Geometry.GeometryType)
                {
                    case esriGeometryType.esriGeometryPoint:
                        IPoint pt = Geometry as IPoint;
                        ListViewItem lstItem = coordGrid.Items.Add("1");
                        lstItem.Tag = pt;
                        if (precision >= 0)
                        {
                            lstItem.SubItems.Add(pt.X.ToString("F" + precision));
                            lstItem.SubItems.Add(pt.Y.ToString("F" + precision));
                        }
                        else
                        {
                            lstItem.SubItems.Add(pt.X.ToString());
                            lstItem.SubItems.Add(pt.Y.ToString());
                        }
                        if (bHasZ)
                        {
                            if (precision >= 0)
                            {
                                lstItem.SubItems.Add(pt.Z.ToString("F" + precision));
                            }
                            else
                            {
                                lstItem.SubItems.Add(pt.Z.ToString());
                            }
                        }
                        break;
                    case esriGeometryType.esriGeometryMultipoint:
                    case esriGeometryType.esriGeometryPolyline:
                    case esriGeometryType.esriGeometryPolygon:
                        ShowCoordinate(index);
                        break;
                }
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(ex.Message);
            }
        }

        /// <summary>
        /// 关键坐标项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void coordGrid_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lvwGeoPart.SelectedItems.Count == 0 || _HookHelper == null) return;
            IPoint pt = null;
            int rowIndex = coordGrid.SelectedItems[0].Index;
            if (Geometry is IPoint)
            {
                pt = Geometry as IPoint;
            }
            else
            {
                IGeometryCollection geoCollection = Geometry as IGeometryCollection;
                IGeometry geo = geoCollection.get_Geometry(Convert.ToInt32(lvwGeoPart.SelectedItems[0].Text) - 1);
                IPointCollection ptCollection = geo as IPointCollection;
                pt = ptCollection.get_Point(rowIndex);                
            }
            ZoomToGeometry(pt);
            FlashHelper.FlashGeometry(pt, (_HookHelper.Hook as IMapControl3));
        }

        /// <summary>
        /// 缩放到该节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnZoom_Click(object sender, EventArgs e)
        {
            if (coordGrid.SelectedItems.Count == 0) return;
            IPoint pt = coordGrid.SelectedItems[0].Tag as IPoint;
            ZoomToGeometry(pt as IGeometry);
            FlashHelper.FlashGeometry(pt, (_HookHelper.Hook as IMapControl3));
        }

        /// <summary>
        /// 移动到该节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPanTo_Click(object sender, EventArgs e)
        {
            if (coordGrid.SelectedItems.Count == 0) return;
            IPoint pt = coordGrid.SelectedItems[0].Tag as IPoint;
            MoveToGeometry(pt as IGeometry);
            FlashHelper.FlashGeometry(pt, (_HookHelper.Hook as IMapControl3));
        }

        /// <summary>
        /// 移动到图形
        /// </summary>
        /// <param name="geometry"></param>
        private void MoveToGeometry(IGeometry geometry)
        {
            IPoint pt;
            if (geometry.GeometryType == esriGeometryType.esriGeometryPoint)
            {
                pt = geometry as IPoint;
            }
            else if (geometry.GeometryType == esriGeometryType.esriGeometryPolygon)
            {
                IArea pArea = geometry as IArea;
                pt = pArea.LabelPoint;
            }
            else
            {
                IEnvelope envelop = geometry.Envelope;
                pt = new ESRI.ArcGIS.Geometry.Point();
                pt.X = envelop.XMin + envelop.Width / 2;
                pt.Y = envelop.YMin + envelop.Height / 2;
                pt.Z = 0;
            }
            IDisplayTransformation displayTransform = _HookHelper.ActiveView.ScreenDisplay.DisplayTransformation;
            IEnvelope extent = displayTransform.VisibleBounds;
            extent.CenterAt(pt);
            displayTransform.VisibleBounds = extent;
            _HookHelper.ActiveView.Refresh();
            //让移动完成后，再进行下一步操作，如闪烁
            _HookHelper.ActiveView.ScreenDisplay.UpdateWindow();
        }

        /// <summary>
        /// 缩放到图形 
        /// </summary>
        /// <param name="geometry"></param>
        private void ZoomToGeometry(IGeometry geometry)
        {
            if (_HookHelper == null) return;
            double zoomScale = Convert.ToDouble(combo_Scale.Text.Substring(2));
            _HookHelper.ActiveView.FocusMap.MapScale = zoomScale;
            IMapControl3 mapControl = _HookHelper.Hook as IMapControl3;
            if (geometry.GeometryType == esriGeometryType.esriGeometryPoint)
            {
                mapControl.CenterAt(geometry as IPoint);
            }
            else
            {
                IEnvelope envelop = geometry.Envelope;
                IPoint ptCenter = new ESRI.ArcGIS.Geometry.Point();
                ptCenter.X = (envelop.XMax + envelop.XMin) / 2;
                ptCenter.Y = (envelop.YMax + envelop.YMin) / 2;
                ptCenter.Z = envelop.ZMin;
                mapControl.CenterAt(ptCenter);
            }
            _HookHelper.ActiveView.Refresh();
            //让缩放完成后，再进行下一步操作，如闪烁
            _HookHelper.ActiveView.ScreenDisplay.UpdateWindow();
        }

        /// <summary>
        /// 关闭窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmPtsCoord_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (_HookHelper == null) return;
            IGraphicsContainer g = _HookHelper.ActiveView.GraphicsContainer;
            g.Reset();
            IElement ele = g.Next();
            while (ele != null)
            {
                if ((ele is IMarkerElement) && (((IMarkerElement)ele).Symbol is ISimpleMarkerSymbol) && (ele.Geometry.GeometryType == esriGeometryType.esriGeometryPoint))
                    g.DeleteElement(ele);
                ele = g.Next();
            }
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, _HookHelper.ActiveView.Extent);
        }

        /// <summary>
        /// 检索结果列表中右键点击，点击点所在行被选中，同时显示菜单"移动到该地物"或"缩放到该地物",
        /// 移动或缩放到该地物后，该地物闪烁显示。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void coordGrid_MouseClick(object sender, MouseEventArgs e)
        {
            //if (e.Button == System.Windows.Forms.MouseButtons.Right)
            //{
            //    int RowIndex = coordGrid.HitTest(e.X, e.Y).Item.Index;
            //    try
            //    {                    
            //        if (RowIndex > -1)
            //        {
            //            for (int i = coordGrid.SelectedItems.Count - 1; i > -1; i--)
            //            {
            //                coordGrid.SelectedItems[i].Selected = false;
            //            }
            //            coordGrid.Items[RowIndex].Selected = true;
            //        }
            //        IPoint pt = null;
            //        if (Geometry is IPoint)
            //        {
            //            pt = Geometry as IPoint;
            //        }
            //        else
            //        {
            //            IGeometryCollection geoCollection = Geometry as IGeometryCollection;
            //            IGeometry geo = geoCollection.get_Geometry(Convert.ToInt32(lvwGeoPart.SelectedItems[0].Text) - 1);
            //            IPointCollection ptCollection = geo as IPointCollection;
            //            pt = ptCollection.get_Point(RowIndex);
            //        }
            //        //增加右键菜单
            //        ContextMenuStrip tocMenuStrip = new ContextMenuStrip();
            //        ToolStripMenuItem itemZoom = new ToolStripMenuItem("缩放到该节点");
            //        itemZoom.Click += delegate(object sender1, EventArgs e1)
            //        {
                       
            //        };
            //        ToolStripMenuItem itemMove = new ToolStripMenuItem("移动到该节点");
            //        itemMove.Click += delegate(object sender1, EventArgs e1)
            //        {
            //            MoveToGeometry(pt as IGeometry);
            //            FlashHelper.FlashGeometry(pt, (_HookHelper.Hook as IMapControl3));
            //        };
            //        tocMenuStrip.Items.AddRange(new ToolStripItem[]
            //                                    {
            //                                        itemZoom,
            //                                        itemMove
            //                                    });
            //        tocMenuStrip.Show(this.coordGrid, e.X, e.Y);
            //    }
            //    catch (Exception ex)
            //    {
            //        MsgHelper.ShowErrorMsgbox(ex.Message);
            //    }
            //}
        }

    }
}
